<?php
/**
 * Created by PhpStorm.
 * User: wincol
 * Date: 2018/3/20
 * Time: 23:06
 */

namespace App\Http\Controllers\Api;


use App\Helper\ErrorCode;
use App\Models\Bookmark;
use App\Models\Chapter;
use App\Models\Content;
use App\Helper\Helper;
use App\Http\Controllers\Controller;
use App\Models\Novel;
use App\Models\SearchHistory;
use App\Models\Sight;
use App\Services\NovelService;
use App\Task\AddRecordTask;
use App\Task\RecordByContentTask;
use Hhxsv5\LaravelS\Swoole\Task\Task;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class NovelController extends Controller
{
    public $novelService;
    public function __construct(NovelService $novelService)
    {
        $this->novelService = $novelService;
    }

    /**
     * @SWG\Get(
     *      path="/api/novel/list",
     *      operationId="getNovelList",
     *      tags={"Novel"},
     *      summary="Get list of novel",
     *      description="
     * http://youarekidding.oss-cn-shanghai.aliyuncs.com/ 图片前缀",
     *      @SWG\Parameter(
     *          name="sort",
     *          description="new：新书榜；hot:热书榜；recommend:推荐榜：默认：无",
     *          required=false,
     *          type="string",
     *          in="query"
     *      ),
     *      @SWG\Parameter(
     *          name="page",
     *          description="页数,不传sort时,才有分页",
     *          required=false,
     *          type="string",
     *          in="query"
     *      ),
     *      @SWG\Parameter(
     *          name="rows",
     *          description="尺寸,不传sort时,才有分页",
     *          required=false,
     *          type="string",
     *          in="query"
     *      ),
     *      @SWG\Response(
     *          response=200,
     *          description="successful operation"
     *       ),
     *       @SWG\Response(response=400, description="Bad request"),
     *       security={
     *           {"api_key_security_example": {}}
     *       }
     *     )
     * Returns list of Novels
     * @param Request $request
     * @return string
     */
    public function getNovelList(Request $request){
        $this->validate($request,[
            'sort'=>'in:new,hot,recommend'
        ]);
        $sort = $request->input('sort');
        $page = $request->input('page',1);
        $rows = $request->input('rows',15);
        switch($sort){
            case 'new':
                $novel_list= Novel::orderByDesc('created_at')->limit($rows);break;
            case 'hot':
                $novel_list= Novel::orderByDesc('title')->limit($rows);break;
            case 'recommend':
                $novel_list= Novel::orderByDesc(DB::raw('rand()'))->limit($rows);break;
            default:
                $novel_list= Novel::limit($rows)->offset($rows*($page-1));break;
        }
        $res['novel_list'] = $novel_list->get(['id as novel_id','title','author','cover']);

        return Helper::returnSuccess($res);
    }

    /**
     * @SWG\Get(
     *      path="/api/chapter/list/{novel_id}/{page}/{rows}",
     *      operationId="getChapterList",
     *      tags={"Novel"},
     *      summary="Get list of Chapter",
     *      description="Returns list of all Chapter by volume_id",
     *      @SWG\Parameter(
     *          name="novel_id",
     *          description="novel id",
     *          required=true,
     *          type="integer",
     *          in="path"
     *      ),
     *      @SWG\Parameter(
     *          name="page",
     *          description="页码",
     *          required=true,
     *          type="integer",
     *          in="path"
     *      ),
     *      @SWG\Parameter(
     *          name="rows",
     *          description="每页行数",
     *          required=true,
     *          type="integer",
     *          in="path"
     *      ),
     *      @SWG\Response(
     *          response=200,
     *          description="successful operation"
     *       ),
     *       @SWG\Response(response=400, description="Bad request"),
     *       security={
     *           {"api_key_security_example": {}}
     *       }
     *     )
     * Returns list of chapter by volume_id
     * @param $novel_id
     * @param $page
     * @param $rows
     * @return string
     */
    public function getChapterList($novel_id, $page, $rows){
        $res['chapter_list'] = Chapter::where('novel_id', $novel_id)
            ->offset(($page-1)*$rows)
            ->limit($rows)
            ->select('id as chapter_id', 'chapter_name', 'abstract')
            ->orderBy('id')
            ->get();
        $res['novel_cover'] = Novel::find($novel_id,['cover']);
        return Helper::returnSuccess($res);
    }
    /**
     * @SWG\Get(
     *      path="/api/content/{chapter_id}",
     *      operationId="getContent",
     *      tags={"Novel"},
     *      summary="Get content",
     *      description="Returns content by chapter_id",
     *      @SWG\Parameter(
     *          name="chapter_id",
     *          description="chapter id",
     *          required=true,
     *          type="integer",
     *          in="path"
     *      ),
     *      @SWG\Parameter(
     *          name="u",
     *          description="user_id",
     *          required=false,
     *          type="integer",
     *          in="query"
     *      ),
     *      @SWG\Parameter(
     *          name="token",
     *          description="token",
     *          required=false,
     *          type="integer",
     *          in="query"
     *      ),
     *      @SWG\Response(
     *          response=200,
     *          description="successful operation"
     *       ),
     *       @SWG\Response(response=400, description="Bad request"),
     *       security={
     *           {"api_key_security_example": {}}
     *       }
     *     )
     * Returns  content by chapter_id
     * @param $chapter_id
     * @return string
     */
    public function getContent($chapter_id, Request $request){
        $user_id = $request->input('u','');
        $content = Content::where('chapter_id', $chapter_id)
            ->first();
        $rs =explode('<br />',nl2br($content['content']));
        $r = array_filter($rs,function($str){
            return mb_strlen($str)>2;
        });
        $r = array_map(function($str){
            return trim($str);
        }, $r);
        $arr = array_values($r);
        $res['chapter_name'] = array_shift($arr);
        $res['content']      = $arr;

        Task::deliver(
            new RecordByContentTask(
                $content['novel_id'],
                $content['chapter_id'],
                mb_strlen($content['content']),
                $user_id
            )
        );
        return Helper::returnSuccess($res);
    }
    /**
     * @SWG\Post(
     *      path="/api/novel/add/bookmark/{chapter_id}/{novel_id}",
     *      tags={"Novel"},
     *      summary="书签",
     *      description="add bookmark
     *     const PARAM_ERROR   = 4440;//参数错误
     *     const SYS_ERROR     = 4444;//系统错误",
     *      @SWG\Parameter(
     *          name="chapter_id",
     *          description="chapter id",
     *          required=true,
     *          type="integer",
     *          in="path"
     *      ),
     *      @SWG\Parameter(
     *          name="novel_id",
     *          description="novel id",
     *          required=true,
     *          type="integer",
     *          in="path"
     *      ),
     *      @SWG\Parameter(
     *          name="u",
     *          description="user_id",
     *          required=true,
     *          type="integer",
     *          in="query"
     *      ),
     *      @SWG\Parameter(
     *          name="token",
     *          description="token",
     *          required=true,
     *          type="string",
     *          in="query"
     *      ),
     *      @SWG\Parameter(
     *          name="timestamp",
     *          description="",
     *          required=true,
     *          type="string",
     *          in="query"
     *      ),
     *      @SWG\Parameter(
     *          name="sign",
     *          description="",
     *          required=true,
     *          type="string",
     *          in="query"
     *      ),
     *      @SWG\Response(
     *          response=200,
     *          description="successful operation"
     *       ),
     *       @SWG\Response(response=400, description="Bad request"),
     *       security={
     *           {"api_key_security_example": {}}
     *       }
     *     )
     * 书签
     * @param $chapter_id
     * @param $novel_id
     * @param Request $request
     * @return string
     */
    public function addBookmark($chapter_id, $novel_id, Request $request){
        $user_id = $request->input('u');
        $chapter = Chapter::where('novel_id',$novel_id)
            ->where('id', $chapter_id)->first();
        if(empty($chapter)){
            return Helper::returnError(ErrorCode::PARAM_ERROR,'小说id不匹配');
        }
        $bookmark = Bookmark::updateOrCreate(['user_id'=>$user_id,'novel_id'=>$novel_id],
            ['user_id'=>$user_id,'novel_id'=>$novel_id,'chapter_id'=>$chapter_id]);
        if($bookmark){
            return Helper::returnSuccess(true);
        }
        return Helper::returnError(ErrorCode::SYS_ERROR);
    }
    /**
     * @SWG\Get(
     *      path="/api/novel/bookmark",
     *      tags={"Novel"},
     *      summary="Get bookmark",
     *      description="Get bookmark",
     *      @SWG\Parameter(
     *          name="u",
     *          description="user_id",
     *          required=true,
     *          type="integer",
     *          in="query"
     *      ),
     *      @SWG\Parameter(
     *          name="token",
     *          description="token",
     *          required=true,
     *          type="string",
     *          in="query"
     *      ),
     *      @SWG\Parameter(
     *          name="timestamp",
     *          description="",
     *          required=true,
     *          type="string",
     *          in="query"
     *      ),
     *      @SWG\Parameter(
     *          name="sign",
     *          description="",
     *          required=true,
     *          type="string",
     *          in="query"
     *      ),
     *      @SWG\Response(
     *          response=200,
     *          description="successful operation"
     *       ),
     *       @SWG\Response(response=400, description="Bad request"),
     *       security={
     *           {"api_key_security_example": {}}
     *       }
     *     )
     * @param Request $request
     * @return string
     */
    public function getBookmark(Request $request){
        $user_id = $request->input('u');
        $bookmark = $this->novelService->getBookMark($user_id);
        return Helper::returnSuccess(['bookmark'=>$bookmark]);
    }
    /**
     * @SWG\Post(
     *      path="/api/novel/add/sight",
     *      tags={"Novel"},
     *      summary="发表感想",
     *      description="add sight",
     *      @SWG\Parameter(
     *          name="u",
     *          description="user_id",
     *          required=true,
     *          type="integer",
     *          in="formData"
     *      ),
     *      @SWG\Parameter(
     *          name="token",
     *          description="token",
     *          required=true,
     *          type="string",
     *          in="formData"
     *      ),
     *      @SWG\Parameter(
     *          name="timestamp",
     *          description="",
     *          required=true,
     *          type="string",
     *          in="query"
     *      ),
     *      @SWG\Parameter(
     *          name="sign",
     *          description="",
     *          required=true,
     *          type="string",
     *          in="query"
     *      ),
     *      @SWG\Parameter(
     *          name="content_id",
     *          description="content_id",
     *          required=true,
     *          type="integer",
     *          in="formData"
     *      ),
     *      @SWG\Parameter(
     *          name="paragraph_id",
     *          description="数组id",
     *          required=true,
     *          type="integer",
     *          in="formData"
     *      ),
     *      @SWG\Parameter(
     *          name="str_id",
     *          description="第几个字",
     *          required=true,
     *          type="integer",
     *          in="formData"
     *      ),
     *      @SWG\Parameter(
     *          name="content",
     *          description="内容",
     *          required=true,
     *          type="string",
     *          in="formData"
     *      ),
     *      @SWG\Response(
     *          response=200,
     *          description="successful operation"
     *       ),
     *       @SWG\Response(response=400, description="Bad request"),
     *       security={
     *           {"api_key_security_example": {}}
     *       }
     *     )
     * @param Request $request
     * @return mixed
     */
    public function addSight(Request $request){
        $user_id       = $request->input('u');
        $content_id    = $request->input('content_id');
        $paragraph_id  = $request->input('paragraph_id');
        $str_id        = $request->input('str_id');
        $sight_content = $request->input('content');

        $content = Content::find($content_id);
        if(!$content){
            return Helper::returnError(ErrorCode::PARAM_ERROR,'文档不存在');
        }
        $sight = Sight::create([
            'user_id'=>$user_id,
            'novel_id'=>$content['novel_id'],
            'chapter_id'=>$content['chapter_id'],
            'content_id'=>$content['id'],
            'sight'=>$sight_content,
            'paragraph_id' =>$paragraph_id,
            'str_id'=>$str_id,
        ]);
        if(!$sight){
            return Helper::returnError(ErrorCode::SYS_ERROR, '添加失败');
        }
        return Helper::returnSuccess(true);
    }
    /**
     * @SWG\Get(
     *      path="/api/novel/sight/{content_id}",
     *      tags={"Novel"},
     *      summary="按章获取感想",
     *      description="数组键名为段落序号",
     *      @SWG\Parameter(
     *          name="u",
     *          description="user_id",
     *          required=true,
     *          type="integer",
     *          in="query"
     *      ),
     *      @SWG\Parameter(
     *          name="token",
     *          description="token",
     *          required=true,
     *          type="string",
     *          in="query"
     *      ),
     *      @SWG\Parameter(
     *          name="timestamp",
     *          description="",
     *          required=true,
     *          type="string",
     *          in="query"
     *      ),
     *      @SWG\Parameter(
     *          name="sign",
     *          description="",
     *          required=true,
     *          type="string",
     *          in="query"
     *      ),
     *      @SWG\Parameter(
     *          name="content_id",
     *          description="content_id",
     *          required=true,
     *          type="integer",
     *          in="path"
     *      ),
     *      @SWG\Response(
     *          response=200,
     *          description="successful operation"
     *       ),
     *       @SWG\Response(response=400, description="Bad request"),
     *       security={
     *           {"api_key_security_example": {}}
     *       }
     *     )
     * @param $content_id
     * @return mixed
     */
    public function getSightByContent($content_id){
        $sights = Sight::where('content_id', $content_id)
            ->get(['paragraph_id', 'str_id', 'sight'])
            ->groupBy('paragraph_id');
        return Helper::returnSuccess($sights);

    }
    /**
     * @SWG\Get(
     *      path="/api/novel/search",
     *      tags={"Novel"},
     *      summary="搜索",
     *      description="支持书名或作者",
     *      @SWG\Parameter(
     *          name="u",
     *          description="user_id",
     *          required=false,
     *          type="integer",
     *          in="query"
     *      ),
     *      @SWG\Parameter(
     *          name="str",
     *          description="关键字",
     *          required=true,
     *          type="string",
     *          in="query"
     *      ),
     *      @SWG\Parameter(
     *          name="timestamp",
     *          description="",
     *          required=true,
     *          type="string",
     *          in="query"
     *      ),
     *      @SWG\Parameter(
     *          name="sign",
     *          description="",
     *          required=true,
     *          type="string",
     *          in="query"
     *      ),
     *      @SWG\Response(
     *          response=200,
     *          description="successful operation"
     *       ),
     *       @SWG\Response(response=400, description="Bad request"),
     *       security={
     *           {"api_key_security_example": {}}
     *       }
     *     )
     * @param Request $request
     * @return mixed
     */
    public function search(Request $request){
        $this->validate($request, [
            'str'=>'required|string|max:32',
            'user_id'=>'integer|min:1',
        ]);
        $str = $request->input('str');
        $user_id = $request->input('u','');
        $novels = Novel::where('title', $str)
            ->orWhere('author', $str)
            ->limit(15)
            ->get(['id','title','author','cover']);
        $data = [
            'user_id'=>$user_id,
            'str'=>$str,
        ];
        $class_arr = [
            SearchHistory::class,
        ];
        $data_arr = [
            $data,
        ];
        Task::deliver(new AddRecordTask($class_arr,$data_arr));
        return Helper::returnSuccess($novels);
    }

}